package com.mxpio.erp.purchase.service.impl;

import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.jpa.model.OrderLineKey;
import com.mxpio.erp.common.purchase.entity.BuyRequestOrder;
import com.mxpio.erp.common.purchase.entity.BuyRequestOrderLine;
import com.mxpio.erp.common.purchase.entity.PurchaseOrder;
import com.mxpio.erp.common.purchase.entity.PurchaseOrderLine;
import com.mxpio.erp.common.purchase.service.BuyRequestOrderLineService;
import com.mxpio.erp.common.purchase.vo.RequestToOrderVO;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service
@Transactional(readOnly = true)
public class BuyRequestOrderLineServiceImpl extends BaseServiceImpl<BuyRequestOrderLine> implements BuyRequestOrderLineService {
    @Transactional(readOnly = false)
    @Override
    public Page<BuyRequestOrderLine> listAuditedPage(Pageable page, Criteria c){
        return JpaUtil.linq(BuyRequestOrderLine.class)
                .collect("bizNo", BuyRequestOrder.class, "bizNo")
                .exists(BuyRequestOrder.class)
                .equalProperty("bizNo", "bizNo")
                .equal("bpmnStatus", OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())
                .end()
                .where(c)
                .paging(page);
    }

    @Transactional(readOnly = false)
    @Override
    public void execToPurcOrder(RequestToOrderVO vo){
        List<BuyRequestOrderLine> buyRequestOrderLines = getLines(vo.getIds());
        if(CollectionUtils.isEmpty(buyRequestOrderLines)){
            return;
        }

        PurchaseOrder purchaseOrder = new PurchaseOrder();
        purchaseOrder.setOrderType("01");
        purchaseOrder.setOrderStatus(OrderStatusEnums.OrderStatus.PLAN.getStatusCode());
        purchaseOrder.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
        purchaseOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
        purchaseOrder.setPnCode(vo.getPnCode());
        purchaseOrder.setPnName(vo.getPnName());
        purchaseOrder.setPnAbbr(vo.getPnAbbr());
        purchaseOrder.setBizMan(vo.getBizMan());
        purchaseOrder.setOrderDate(new Date());
        JpaUtil.save(purchaseOrder);


        List<PurchaseOrderLine> purchaseOrderLines = new ArrayList<>();
        Map<String,PurchaseOrderLine> purchaseOrderLineMap = new HashMap<>();

        for(BuyRequestOrderLine buyLine:buyRequestOrderLines){
            PurchaseOrderLine purchaseOrderLine = orderLineFromRequestLine(buyLine,purchaseOrder);
            if(StringUtils.equals(vo.getMergeItem(),"1")){
                if(purchaseOrderLineMap.containsKey(buyLine.getItemCode())){
                    mergeOrderLine(purchaseOrderLine,purchaseOrderLineMap.get(buyLine.getItemCode()));
                }
                else{
                    purchaseOrderLines.add(purchaseOrderLine);
                    purchaseOrderLineMap.put(buyLine.getItemCode(),purchaseOrderLine);
                }
            }
            else {
                purchaseOrderLines.add(purchaseOrderLine);
            }
            buyLine.setLineStatus(OrderStatusEnums.BuyRequestLineStatus.EXECUTE.getStatusCode());
            JpaUtil.update(buyLine);
        }
        int i=1;
        for(PurchaseOrderLine line:purchaseOrderLines){
            line.setLineNo(String.valueOf(i++));
            JpaUtil.save(line);
        }
    }

    private List<BuyRequestOrderLine> getLines(String ids){
        String[] id = ids.split(",");
        List<BuyRequestOrderLine> buyRequestOrders = new ArrayList<>();
        for(String key : id){
            String[] pk = key.split(":");
            OrderLineKey lineKey = new OrderLineKey();
            lineKey.setBizNo(pk[0]);
            lineKey.setLineNo(pk[1]);
            BuyRequestOrderLine line = this.getById(BuyRequestOrderLine.class,lineKey);
            buyRequestOrders.add(line);
        }
        return buyRequestOrders;
    }

    private PurchaseOrderLine orderLineFromRequestLine(BuyRequestOrderLine buyLine,PurchaseOrder purchaseOrder){
        PurchaseOrderLine orderLine = new PurchaseOrderLine();
        orderLine.setBizNo(purchaseOrder.getBizNo());
        orderLine.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
        orderLine.setItemCode(buyLine.getItemCode());
        orderLine.setItemName(buyLine.getItemName());
        orderLine.setItemSpec(buyLine.getItemSpec());
        orderLine.setReqQuantity(buyLine.getQuantity());
        orderLine.setSuggestOrderDate(buyLine.getSuggestOrderDate());
        orderLine.setSuggestArriveDate(buyLine.getArriveDate());
        return orderLine;
    }

    private void mergeOrderLine(PurchaseOrderLine source,PurchaseOrderLine target){
        target.setReqQuantity(target.getReqQuantity().add(source.getReqQuantity()));
        target.setSuggestOrderDate(target.getSuggestOrderDate().compareTo(source.getSuggestOrderDate())<0?target.getSuggestOrderDate():source.getSuggestOrderDate());
        target.setSuggestArriveDate(target.getSuggestArriveDate().compareTo(source.getSuggestArriveDate())<0?target.getSuggestArriveDate():source.getSuggestArriveDate());
    }

}
